﻿using Common.Extension;
using System.Text.RegularExpressions;

namespace DesignModeConsole.行为型.解释器模式.自定义1;

/// <summary>
/// 告警规则解释器
/// </summary>
public class IdentityRuleInterpreter3 : IAlertRuleExpression3
{
    private IAlertRuleExpression3 _alertRuleExpression;

    public IdentityRuleInterpreter3(string ruleExpression)
    {
        // 多个空格合并到一个空格
        var strArray = Regex.Replace(ruleExpression, @"\s+", " ").Split(" ");
        if (strArray.Length < 3)
            throw new ArgumentException("无效的格式");

        var handlerArray = new List<string>();

        // 处理可能非括号和对应的字段名连接到一块的情况
        foreach (var str in strArray)
        {
            RecursionSplit(str);
        }

        HandlerExpression(handlerArray);

        // 递归分割
        void RecursionSplit(string str)
        {
            if (str.Length != 1)
            {
                if (str.StartsWith("("))
                {
                    handlerArray.Add("(");
                    RecursionSplit(str.Substring(1, str.Length - 1));
                }
                else if (str.EndsWith(")"))
                {
                    var endTramArray = RecursionEndTrim(str);
                    endTramArray.Reverse();
                    handlerArray.AddRange(endTramArray);
                }
                else
                {
                    handlerArray.Add(str);
                }
            }
            else if (str.IsNotNullOrEmpty())
            {
                handlerArray.Add(str);
            }
        }

        // 递归去除最后的 )
        List<string> RecursionEndTrim(string str)
        {
            var result = new List<string>();
            if (str.EndsWith(")"))
            {
                result.Add(")");
                var subStr = str[..^1];
                result.AddRange(RecursionEndTrim(subStr));
            }
            else
            {
                result.Add(str);
            }

            return result;
        }
    }

    public IdentityRuleInterpreter3(IEnumerable<string> param)
    {
        var strArray = string.Join(" ", param).Split(" ");
        HandlerExpression(strArray);
    }

    public bool Interpret(string tableName, string columnName)
    {
        return _alertRuleExpression.Interpret(tableName, columnName);
    }

    private void HandlerExpression(IReadOnlyList<string> strArray)
    {
        /*
         处理逻辑：循环根据空格分割后的内容，然后取到第一组，然后处理
        将另外的那部分继续循环按照第一组的方式处理
         */

        // 括号的数量
        var bracketNum = 0;
        //是否是通过and连接操作
        var isAndConnector = false;

        // 这一组表达式是否结束
        var isOver = false;

        // 左侧集合
        var leftList = new List<string>();
        var i = 0;
        for (; i < strArray.Count; i++)
        {
            var curr = strArray[i];
            if (curr is " ")
                continue;

            switch (curr)
            {
                case "(":
                    if (bracketNum > 0)
                    {
                        leftList.Add(curr);
                    }

                    bracketNum++;
                    break;

                case ")":
                    // 如果括号的数量大于1 那么就拼接当前的节点，并且标注括号数量减一
                    if (bracketNum > 1)
                    {
                        leftList.Add(curr);
                    }

                    bracketNum--;
                    break;

                case "and":

                    // 如果没有组，那么就设置存在and连接，当前表达式结束
                    if (bracketNum == 0)
                    {
                        isAndConnector = true;
                        isOver = true;
                    }
                    else
                    {
                        leftList.Add(curr);
                    }

                    break;

                case "or":

                    // 如果没有组，那么就设置没有and连接，然后当前表达式结束
                    if (bracketNum == 0)
                    {
                        isAndConnector = false;
                        isOver = true;
                    }
                    else
                    {
                        leftList.Add(curr);
                    }

                    break;

                default:
                    leftList.Add(curr);
                    break;
            }

            // 如果这一组结束
            if (isOver)
            {
                i++;
                break;
            }
        }

        var rightList = strArray.Skip(i).Take(strArray.Count - 1).ToList();
        if (rightList.Count == 0)
        {
            // 如果左侧内容只有三个，那么就当成一个表达式去处理，否则再次进行规则解析处理
            _alertRuleExpression = leftList.Count == 3
                ? new AndExpression3(leftList)
                : new IdentityRuleInterpreter3(leftList);
        }
        else
        {
            var list3 = new List<IAlertRuleExpression3>();
            //如果左侧只有三个 那么就当成一组去拼接
            if (leftList.Count == 3)
            {
                list3.Add(new AndExpression3(leftList));
            }
            else
            {
                list3.Add(new IdentityRuleInterpreter3(leftList));
            }

            // 右侧和上面同理
            if (rightList.Count == 3)
            {
                list3.Add(new AndExpression3(rightList));
            }
            else
            {
                list3.Add(new IdentityRuleInterpreter3(rightList));
            }

            _alertRuleExpression = isAndConnector ? new AndExpression3(list3) : new OrExpression3(list3);
        }
    }
}